package com.haiyou.mini.programs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.haiyou.common.exception.BusinessException;
import com.haiyou.common.util.FileUtil;
import com.haiyou.mini.programs.config.WxMiniConfig;
import com.haiyou.mini.programs.service.WxUploadService;
import com.haiyou.mini.programs.v3.V3Util;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.util.UUID;

/**
 * 微信上传
 */
@Slf4j
@RequiredArgsConstructor
public class WxUploadServiceImpl implements WxUploadService {

    private final WxMiniConfig wxPayConfig;

    @Override
    public String v3Upload(String picUrl) {
        try {
            //时间戳
            String timestamp = Long.toString(System.currentTimeMillis() / 1000);
            //随机数
            String nonce_str = UUID.randomUUID().toString();

            //下载文件
            File file = FileUtil.download(picUrl);

            String filename = file.getName();
            //文件sha256
            String fileSha256 = DigestUtils.sha256Hex(new FileInputStream(file));

            //拼签名串
            StringBuffer sb = new StringBuffer();
            sb.append("POST").append("\n");
            sb.append("/v3/marketing/favor/media/image-upload").append("\n");
            sb.append(timestamp).append("\n");
            sb.append(nonce_str).append("\n");
            sb.append("{\"filename\":\"" + filename + "\",\"sha256\":\"" + fileSha256 + "\"}").append("\n");
            log.info("签名原串：{}", sb.toString());

            //计算签名
            String sign = new String(Base64.encodeBase64(V3Util.signRSA(sb.toString(), V3Util.privateKey(wxPayConfig.getRsaPrivateKeyFile(), true))));
            log.info("签名sign值：{}", sign);

            //拼装http头的Authorization内容
            String authorization = "WECHATPAY2-SHA256-RSA2048 mchid=\"" + wxPayConfig.getMchID() + "\",nonce_str=\"" + nonce_str + "\",signature=\"" + sign + "\",timestamp=\"" + timestamp + "\",serial_no=\"" + wxPayConfig.getSerialNo() + "\"";
            log.info("authorization值：{}", authorization);

            //接口URL
            String url = "https://api.mch.weixin.qq.com/v3/marketing/favor/media/image-upload";
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);

            //设置头部
            httpPost.addHeader("Accept", "application/json");
            httpPost.addHeader("Content-Type", "multipart/form-data");
            httpPost.addHeader("Authorization", authorization);

            //创建MultipartEntityBuilder
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            //设置boundary
            multipartEntityBuilder.setBoundary(nonce_str);
            multipartEntityBuilder.setCharset(Charset.forName("UTF-8"));
            //设置meta内容
            multipartEntityBuilder.addTextBody("meta", "{\"filename\":\"" + filename + "\",\"sha256\":\"" + fileSha256 + "\"}", ContentType.APPLICATION_JSON);
            //设置图片内容
            multipartEntityBuilder.addBinaryBody("file", file, ContentType.create("image/jpg"), filename);
            //放入内容
            httpPost.setEntity(multipartEntityBuilder.build());

            //获取返回内容
            CloseableHttpResponse response = httpclient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            String resContent = new String(V3Util.InputStream2Byte(httpEntity.getContent()));
            log.info("返回内容：{}", resContent);
            JSONObject jsonObject = JSON.parseObject(resContent);
            EntityUtils.consume(httpEntity);
            response.close();

            if (jsonObject == null || !jsonObject.containsKey("media_url")) {
                throw new BusinessException("图片上传异常");
            }
            return jsonObject.getString("media_url");
        } catch (Exception e) {
            log.error("上传图片，发送POST请求异常！{},{}", e.getMessage(), e);
        }
        throw new BusinessException("图片上传异常");
    }


}
